home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 24 / CU Amiga Magazine's Super CD-ROM 24 (1998)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1998-07].iso / CUCD / Utilities / vim-5.1 / src / ex_getln.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-03-28  |  59.9 KB  |  2,525 lines

  1. /* vi:set ts=8 sts=4 sw=4:
  2.  *
  3.  * VIM - Vi IMproved    by Bram Moolenaar
  4.  *
  5.  * Do ":help uganda"  in Vim to read copying and usage conditions.
  6.  * Do ":help credits" in Vim to see a list of people who contributed.
  7.  */
  8.  
  9. /*
  10.  * ex_getln.c: Functions for entering and editing an Ex command line.
  11.  */
  12.  
  13. #include "vim.h"
  14.  
  15. /*
  16.  * Variables shared between getcmdline(), redrawcmdline() and others.
  17.  * These need to be saved when using CTRL-R |, that's why they are in a
  18.  * structure.
  19.  */
  20. struct cmdline_info
  21. {
  22.     char_u  *cmdbuff;        /* pointer to command line buffer */
  23.     int         cmdbufflen;    /* length of cmdbuff */
  24.     int         cmdlen;        /* number of chars on command line */
  25.     int         cmdpos;        /* current cursor position */
  26.     int         cmdspos;        /* cursor column on screen */
  27.     int         cmdfirstc;        /* ':', '/', '?', '=' or NUL */
  28.     int         cmdindent;        /* number of spaces before cmdline */
  29.     int         overstrike;    /* Typing mode on the command line.  Shared by
  30.                    getcmdline() and put_on_cmdline(). */
  31. };
  32.  
  33. static struct cmdline_info ccline;    /* current cmdline_info */
  34.  
  35. static int    cmd_numfiles = -1;    /* number of files found by
  36.                             file name completion */
  37. static char_u    **(history[HIST_COUNT]) = {NULL, NULL, NULL};
  38. static int    hisidx[HIST_COUNT] = {-1, -1, -1};  /* last entered entry */
  39. static int    hislen = 0;        /* actual length of history tables */
  40.  
  41. #ifdef RIGHTLEFT
  42. static int    cmd_hkmap = 0;        /* Hebrew mapping during command line */
  43. #endif
  44.  
  45. #ifdef FKMAP
  46. static int        cmd_fkmap = 0;    /* Farsi mapping during command line */
  47. #endif
  48.  
  49. static int    hist_char2type __ARGS((int c));
  50. static void    init_history __ARGS((void));
  51.  
  52. static int    in_history __ARGS((int, char_u *, int));
  53. static void    alloc_cmdbuff __ARGS((int len));
  54. static int    realloc_cmdbuff __ARGS((int len));
  55. static void    putcmdline __ARGS((int));
  56. static void    redrawcmd __ARGS((void));
  57. static void    cursorcmd __ARGS((void));
  58. static int    ccheck_abbr __ARGS((int));
  59. static int    nextwild __ARGS((int));
  60. static int    showmatches __ARGS((void));
  61. static void    set_expand_context __ARGS((void));
  62. static int    ExpandFromContext __ARGS((char_u *, int *, char_u ***, int, int));
  63.  
  64. /*
  65.  * getcmdline() - accept a command line starting with firstc.
  66.  *
  67.  * firstc == ':'        get ":" command line.
  68.  * firstc == '/' or '?'        get search pattern
  69.  * firstc == '='        get expression
  70.  * firstc == NUL        get text for :insert command
  71.  *
  72.  * The line is collected in ccline.cmdbuff, which is reallocated to fit the
  73.  * command line.
  74.  *
  75.  * Careful: getcmdline() can be called recursively!
  76.  *
  77.  * Return pointer to allocated string if there is a commandline, NULL
  78.  * otherwise.
  79.  */
  80.     char_u *
  81. getcmdline(firstc, count, indent)
  82.     int        firstc;
  83.     long    count;        /* only used for incremental search */
  84.     int        indent;        /* indent for inside conditionals */
  85. {
  86.     int        c;
  87. #ifdef DIGRAPHS
  88.     int        cc;
  89. #endif
  90.     int        i;
  91.     int        j;
  92.     char_u    *p;
  93.     int        hiscnt;            /* current history line in use */
  94.     char_u    *lookfor = NULL;    /* string to match */
  95.     int        gotesc = FALSE;        /* TRUE when <ESC> just typed */
  96.     int        do_abbr;        /* when TRUE check for abbr. */
  97.     int        histype;        /* history type to be used */
  98. #ifdef EXTRA_SEARCH
  99.     FPOS    old_cursor;
  100.     colnr_t    old_curswant;
  101.     colnr_t    old_leftcol;
  102.     linenr_t    old_topline;
  103.     linenr_t    old_botline;
  104.     int        did_incsearch = FALSE;
  105.     int        incsearch_postponed = FALSE;
  106. #endif
  107.     int        save_msg_scroll = msg_scroll;
  108.     int        save_State = State;    /* remember State when called */
  109.     int        some_key_typed = FALSE;    /* one of the keys was typed */
  110. #ifdef USE_MOUSE
  111.     /* mouse drag and release events are ignored, unless they are
  112.      * preceded with a mouse down event */
  113.     int        ignore_drag_release = TRUE;
  114. #endif
  115. #ifdef USE_SNIFF
  116.     want_sniff_request = 0;
  117. #endif
  118.  
  119.     ccline.overstrike = FALSE;            /* always start in insert mode */
  120. #ifdef EXTRA_SEARCH
  121.     old_cursor = curwin->w_cursor;        /* needs to be restored later */
  122.     old_curswant = curwin->w_curswant;
  123.     old_leftcol = curwin->w_leftcol;
  124.     old_topline = curwin->w_topline;
  125.     old_botline = curwin->w_botline;
  126. #endif
  127.  
  128.     /*
  129.      * set some variables for redrawcmd()
  130.      */
  131.     ccline.cmdfirstc = firstc;
  132.     ccline.cmdindent = indent;
  133.     alloc_cmdbuff(exmode_active ? 250 : 0); /* alloc initial ccline.cmdbuff */
  134.     if (ccline.cmdbuff == NULL)
  135.     return NULL;                /* out of memory */
  136.     ccline.cmdlen = ccline.cmdpos = 0;
  137.     if (firstc)
  138.     ccline.cmdspos = 1 + indent;
  139.     else
  140.     ccline.cmdspos = 0 + indent;
  141.  
  142.     redir_off = TRUE;        /* don't redirect the typed command */
  143.     i = msg_scrolled;
  144.     msg_scrolled = 0;        /* avoid wait_return message */
  145.     gotocmdline(TRUE);
  146.     msg_scrolled += i;
  147.     if (firstc)
  148.     msg_putchar(firstc);
  149.     while (indent-- > 0)
  150.     msg_putchar(' ');
  151.  
  152.     /*
  153.      * Avoid scrolling when called by a recursive do_cmdline(), e.g. when doing
  154.      * ":@0" when register 0 doesn't contain a CR.
  155.      */
  156.     msg_scroll = FALSE;
  157.  
  158.     State = CMDLINE;
  159. #ifdef USE_MOUSE
  160.     setmouse();
  161. #endif
  162.  
  163.     init_history();
  164.     hiscnt = hislen;        /* set hiscnt to impossible history value */
  165.     histype = hist_char2type(firstc);
  166.  
  167. #ifdef DIGRAPHS
  168.     do_digraph(-1);        /* init digraph typahead */
  169. #endif
  170.  
  171.     /* collect the command string, handling editing keys */
  172.     for (;;)
  173.     {
  174. #ifdef USE_GUI_WIN32
  175.     dont_scroll = FALSE;    /* allow scrolling here */
  176. #endif
  177.     cursorcmd();        /* set the cursor on the right spot */
  178.     c = vgetc();
  179.     if (KeyTyped)
  180.     {
  181.         some_key_typed = TRUE;
  182. #ifdef RIGHTLEFT
  183.         if (cmd_hkmap)
  184.         c = hkmap(c);
  185. # ifdef FKMAP
  186.         if (cmd_fkmap)
  187.         c = cmdl_fkmap(c);
  188. # endif
  189. #endif
  190.     }
  191.  
  192.     /*
  193.      * Ignore got_int when CTRL-C was typed here.
  194.      * Don't ignore it in :global, we really need to break then, e.g., for
  195.      * ":g/pat/normal /pat" (without the <CR>).
  196.      */
  197.     if ((c == Ctrl('C')
  198. #ifdef UNIX
  199.         || c == intr_char
  200. #endif
  201.                 ) && !global_busy)
  202.         got_int = FALSE;
  203.  
  204.     /* free old command line when finished moving around in the history
  205.      * list */
  206.     if (lookfor
  207.         && c != K_S_DOWN && c != K_S_UP && c != K_DOWN && c != K_UP
  208.         && c != K_PAGEDOWN && c != K_PAGEUP
  209.         && c != K_KPAGEDOWN && c != K_KPAGEUP
  210.         && c != K_LEFT && c != K_RIGHT
  211.         && (cmd_numfiles > 0 || (c != Ctrl('P') && c != Ctrl('N'))))
  212.     {
  213.         vim_free(lookfor);
  214.         lookfor = NULL;
  215.     }
  216.  
  217.     /*
  218.      * <S-Tab> works like CTRL-P (unless 'wc' is <S-Tab>).
  219.      */
  220.     if (c != p_wc && c == K_S_TAB && cmd_numfiles != -1)
  221.         c = Ctrl('P');
  222.  
  223.     /* free expanded names when finished walking through matches */
  224.     if (cmd_numfiles != -1 && !(c == p_wc && KeyTyped) && c != Ctrl('N') &&
  225.             c != Ctrl('P') && c != Ctrl('A') && c != Ctrl('L'))
  226.         (void)ExpandOne(NULL, NULL, 0, WILD_FREE);
  227.  
  228. #ifdef DIGRAPHS
  229.     c = do_digraph(c);
  230. #endif
  231.  
  232.     if (c == '\n' || c == '\r' || (c == ESC && (!KeyTyped ||
  233.                      vim_strchr(p_cpo, CPO_ESC) != NULL)))
  234.     {
  235.         gotesc = FALSE;    /* Might have typed ESC previously, don't
  236.                    truncate the cmdline now. */
  237.         if (ccheck_abbr(c + ABBR_OFF))
  238.         goto cmdline_changed;
  239.         windgoto(msg_row, 0);
  240.         out_flush();
  241.         break;
  242.     }
  243.  
  244.     /* hitting <ESC> twice means: abandon command line */
  245.     /* wildcard expansion is only done when the key is really typed,
  246.      * not when it comes from a macro */
  247.     if (c == p_wc && !gotesc && KeyTyped)
  248.     {
  249.         if (cmd_numfiles > 0)   /* typed p_wc twice */
  250.         i = nextwild(WILD_NEXT);
  251.         else            /* typed p_wc first time */
  252.         i = nextwild(WILD_EXPAND_KEEP);
  253.         if (c == ESC)
  254.         gotesc = TRUE;
  255.         if (i == OK)
  256.         goto cmdline_changed;
  257.     }
  258.     gotesc = FALSE;
  259.  
  260.     /* <S-Tab> goes to last match, in a clumsy way */
  261.     if (c == K_S_TAB && KeyTyped)
  262.     {
  263.         if (nextwild(WILD_EXPAND_KEEP) == OK
  264.             && nextwild(WILD_PREV) == OK
  265.             && nextwild(WILD_PREV) == OK)
  266.         goto cmdline_changed;
  267.     }
  268.  
  269.     if (c == NUL || c == K_ZERO)        /* NUL is stored as NL */
  270.         c = NL;
  271.  
  272.     do_abbr = TRUE;        /* default: check for abbreviation */
  273.     switch (c)
  274.     {
  275.     case K_BS:
  276.     case Ctrl('H'):
  277.     case K_DEL:
  278.     case Ctrl('W'):
  279. #ifdef FKMAP
  280.         if (cmd_fkmap && c == K_BS)
  281.             c = K_DEL;
  282. #endif
  283.         /*
  284.          * delete current character is the same as backspace on next
  285.          * character, except at end of line
  286.          */
  287.         if (c == K_DEL && ccline.cmdpos != ccline.cmdlen)
  288.             ++ccline.cmdpos;
  289.         if (ccline.cmdpos > 0)
  290.         {
  291.             j = ccline.cmdpos;
  292.             if (c == Ctrl('W'))
  293.             {
  294.             while (ccline.cmdpos &&
  295.                    vim_isspace(ccline.cmdbuff[ccline.cmdpos - 1]))
  296.                 --ccline.cmdpos;
  297.             i = vim_iswordc(ccline.cmdbuff[ccline.cmdpos - 1]);
  298.             while (ccline.cmdpos && !vim_isspace(
  299.                      ccline.cmdbuff[ccline.cmdpos - 1]) &&
  300.                 vim_iswordc(
  301.                       ccline.cmdbuff[ccline.cmdpos - 1]) == i)
  302.                 --ccline.cmdpos;
  303.             }
  304.             else
  305.             --ccline.cmdpos;
  306.             ccline.cmdlen -= j - ccline.cmdpos;
  307.             i = ccline.cmdpos;
  308.             while (i < ccline.cmdlen)
  309.             ccline.cmdbuff[i++] = ccline.cmdbuff[j++];
  310.             redrawcmd();
  311.         }
  312.         else if (ccline.cmdlen == 0 && c != Ctrl('W'))
  313.         {
  314.             vim_free(ccline.cmdbuff);    /* no commandline to return */
  315.             ccline.cmdbuff = NULL;
  316.             msg_col = 0;
  317.             msg_putchar(' ');        /* delete ':' */
  318.             redraw_cmdline = TRUE;
  319.             goto returncmd;        /* back to cmd mode */
  320.         }
  321.         goto cmdline_changed;
  322.  
  323.     case K_INS:
  324. #ifdef FKMAP
  325.         /* if Farsi mode set, we are in reverse insert mode -
  326.            Do not change the mode */
  327.         if (cmd_fkmap)
  328.             beep_flush();
  329.         else
  330. #endif
  331.         ccline.overstrike = !ccline.overstrike;
  332. #ifdef USE_GUI
  333.         if (gui.in_use)
  334.             gui_upd_cursor_shape();    /* change shape of cursor */
  335. #endif
  336.         goto cmdline_not_changed;
  337.  
  338. /*    case '@':   only in very old vi */
  339.     case Ctrl('U'):
  340.         ccline.cmdpos = 0;
  341.         ccline.cmdlen = 0;
  342.         if (firstc)
  343.             ccline.cmdspos = 1 + ccline.cmdindent;
  344.         else
  345.             ccline.cmdspos = 0 + ccline.cmdindent;
  346.         redrawcmd();
  347.         goto cmdline_changed;
  348.  
  349.     case ESC:    /* get here if p_wc != ESC or when ESC typed twice */
  350.     case Ctrl('C'):
  351.         gotesc = TRUE;        /* will free ccline.cmdbuff after putting
  352.                        it in history */
  353.         goto returncmd;        /* back to cmd mode */
  354.  
  355.     case Ctrl('R'):            /* insert register */
  356. #ifdef USE_GUI_WIN32
  357.         dont_scroll = TRUE; /* disallow scrolling here */
  358. #endif
  359.         putcmdline('"');
  360.         ++no_mapping;
  361.         c = vgetc();
  362.         --no_mapping;
  363. #ifdef WANT_EVAL
  364.         /*
  365.          * Insert the result of an expression.
  366.          * Need to save the current command line, to be able to enter
  367.          * a new one...
  368.          */
  369.         if (c == '=')
  370.         {
  371.             struct cmdline_info        save_ccline;
  372.  
  373.             if (firstc == '=')    /* can't do this recursively */
  374.             {
  375.             beep_flush();
  376.             c = ESC;
  377.             }
  378.             else
  379.             {
  380.             save_ccline = ccline;
  381.             c = get_expr_register();
  382.             ccline = save_ccline;
  383.             }
  384.         }
  385. #endif
  386.         if (c != ESC)        /* use ESC to cancel inserting register */
  387.             cmdline_paste(c);
  388.         redrawcmd();
  389.         goto cmdline_changed;
  390.  
  391.     case Ctrl('D'):
  392.         {
  393.         if (showmatches() == FAIL)
  394.             break;    /* Use ^D as normal char instead */
  395.  
  396.         redrawcmd();
  397.         continue;    /* don't do incremental search now */
  398.         }
  399.  
  400.     case K_RIGHT:
  401.     case K_S_RIGHT:
  402.         do
  403.         {
  404.             if (ccline.cmdpos >= ccline.cmdlen)
  405.             break;
  406.             ccline.cmdspos += charsize(ccline.cmdbuff[ccline.cmdpos]);
  407.             ++ccline.cmdpos;
  408.         }
  409.         while ((c == K_S_RIGHT || (mod_mask & MOD_MASK_CTRL))
  410.             && ccline.cmdbuff[ccline.cmdpos] != ' ');
  411.         goto cmdline_not_changed;
  412.  
  413.     case K_LEFT:
  414.     case K_S_LEFT:
  415.         do
  416.         {
  417.             if (ccline.cmdpos <= 0)
  418.             break;
  419.             --ccline.cmdpos;
  420.             ccline.cmdspos -= charsize(ccline.cmdbuff[ccline.cmdpos]);
  421.         }
  422.         while ((c == K_S_LEFT || (mod_mask & MOD_MASK_CTRL))
  423.             && ccline.cmdbuff[ccline.cmdpos - 1] != ' ');
  424.         goto cmdline_not_changed;
  425.  
  426. #if defined(USE_MOUSE) || defined(FKMAP)
  427.     case K_IGNORE:
  428. #endif
  429. #ifdef USE_MOUSE
  430.     case K_MIDDLEDRAG:
  431.     case K_MIDDLERELEASE:
  432.         goto cmdline_not_changed;   /* Ignore mouse */
  433.  
  434.     case K_MIDDLEMOUSE:
  435. # ifdef USE_GUI
  436.         /* When GUI is active, also paste when 'mouse' is empty */
  437.         if (!gui.in_use)
  438. # endif
  439.             if (!mouse_has(MOUSE_COMMAND))
  440.             goto cmdline_not_changed;   /* Ignore mouse */
  441. # ifdef USE_GUI
  442.         if (gui.in_use)
  443.             cmdline_paste('*');
  444.         else
  445. # endif
  446.             cmdline_paste(0);
  447.         redrawcmd();
  448.         goto cmdline_changed;
  449.  
  450.     case K_LEFTDRAG:
  451.     case K_LEFTRELEASE:
  452.     case K_RIGHTDRAG:
  453.     case K_RIGHTRELEASE:
  454.         if (ignore_drag_release)
  455.             goto cmdline_not_changed;
  456.         /* FALLTHROUGH */
  457.     case K_LEFTMOUSE:
  458.     case K_RIGHTMOUSE:
  459.         if (c == K_LEFTRELEASE || c == K_RIGHTRELEASE)
  460.             ignore_drag_release = TRUE;
  461.         else
  462.             ignore_drag_release = FALSE;
  463. # ifdef USE_GUI
  464.         /* When GUI is active, also move when 'mouse' is empty */
  465.         if (!gui.in_use)
  466. # endif
  467.             if (!mouse_has(MOUSE_COMMAND))
  468.             goto cmdline_not_changed;   /* Ignore mouse */
  469.         if (firstc)
  470.             ccline.cmdspos = 1 + ccline.cmdindent;
  471.         else
  472.             ccline.cmdspos = 0 + ccline.cmdindent;
  473.         for (ccline.cmdpos = 0; ccline.cmdpos < ccline.cmdlen;
  474.                                   ++ccline.cmdpos)
  475.         {
  476.             i = charsize(ccline.cmdbuff[ccline.cmdpos]);
  477.             if (mouse_row <= cmdline_row + ccline.cmdspos / Columns &&
  478.                      mouse_col < ccline.cmdspos % Columns + i)
  479.             break;
  480.             ccline.cmdspos += i;
  481.         }
  482.         goto cmdline_not_changed;
  483. #endif    /* USE_MOUSE */
  484.  
  485. #ifdef USE_GUI
  486.     case K_SCROLLBAR:
  487.         if (!msg_scrolled)
  488.         {
  489.             gui_do_scroll();
  490.             redrawcmd();
  491.         }
  492.         goto cmdline_not_changed;
  493.  
  494.     case K_HORIZ_SCROLLBAR:
  495.         if (!msg_scrolled)
  496.         {
  497.             gui_do_horiz_scroll();
  498.             redrawcmd();
  499.         }
  500.         goto cmdline_not_changed;
  501. #endif
  502.  
  503.     case Ctrl('B'):        /* begin of command line */
  504.     case K_HOME:
  505.     case K_KHOME:
  506.         ccline.cmdpos = 0;
  507.         if (firstc)
  508.             ccline.cmdspos = 1 + ccline.cmdindent;
  509.         else
  510.             ccline.cmdspos = 0 + ccline.cmdindent;
  511.         goto cmdline_not_changed;
  512.  
  513.     case Ctrl('E'):        /* end of command line */
  514.     case K_END:
  515.     case K_KEND:
  516.         ccline.cmdpos = ccline.cmdlen;
  517.         ccline.cmdbuff[ccline.cmdlen] = NUL;
  518.         if (firstc)
  519.             ccline.cmdspos = 1 + ccline.cmdindent;
  520.         else
  521.             ccline.cmdspos = 0 + ccline.cmdindent;
  522.         ccline.cmdspos += vim_strsize(ccline.cmdbuff);
  523.         goto cmdline_not_changed;
  524.  
  525.     case Ctrl('A'):        /* all matches */
  526.         if (nextwild(WILD_ALL) == FAIL)
  527.             break;
  528.         goto cmdline_changed;
  529.  
  530.     case Ctrl('L'):        /* longest common part */
  531.         if (nextwild(WILD_LONGEST) == FAIL)
  532.             break;
  533.         goto cmdline_changed;
  534.  
  535.     case Ctrl('N'):        /* next match */
  536.     case Ctrl('P'):        /* previous match */
  537.         if (cmd_numfiles > 0)
  538.         {
  539.             if (nextwild((c == Ctrl('P')) ? WILD_PREV : WILD_NEXT)
  540.                                       == FAIL)
  541.             break;
  542.             goto cmdline_changed;
  543.         }
  544.  
  545.     case K_UP:
  546.     case K_DOWN:
  547.     case K_S_UP:
  548.     case K_S_DOWN:
  549.     case K_PAGEUP:
  550.     case K_KPAGEUP:
  551.     case K_PAGEDOWN:
  552.     case K_KPAGEDOWN:
  553.         if (hislen == 0 || firstc == NUL)    /* no history */
  554.             goto cmdline_not_changed;
  555.  
  556.         i = hiscnt;
  557.  
  558.         /* save current command string so it can be restored later */
  559.         ccline.cmdbuff[ccline.cmdlen] = NUL;
  560.         if (lookfor == NULL)
  561.         {
  562.             if ((lookfor = vim_strsave(ccline.cmdbuff)) == NULL)
  563.             goto cmdline_not_changed;
  564.             lookfor[ccline.cmdpos] = NUL;
  565.         }
  566.  
  567.         j = STRLEN(lookfor);
  568.         for (;;)
  569.         {
  570.             /* one step backwards */
  571.             if (c == K_UP || c == K_S_UP || c == Ctrl('P') ||
  572.                 c == K_PAGEUP || c == K_KPAGEUP)
  573.             {
  574.             if (hiscnt == hislen)    /* first time */
  575.                 hiscnt = hisidx[histype];
  576.             else if (hiscnt == 0 && hisidx[histype] != hislen - 1)
  577.                 hiscnt = hislen - 1;
  578.             else if (hiscnt != hisidx[histype] + 1)
  579.                 --hiscnt;
  580.             else            /* at top of list */
  581.             {
  582.                 hiscnt = i;
  583.                 break;
  584.             }
  585.             }
  586.             else    /* one step forwards */
  587.             {
  588.             /* on last entry, clear the line */
  589.             if (hiscnt == hisidx[histype])
  590.             {
  591.                 hiscnt = hislen;
  592.                 break;
  593.             }
  594.  
  595.             /* not on a history line, nothing to do */
  596.             if (hiscnt == hislen)
  597.                 break;
  598.             if (hiscnt == hislen - 1)   /* wrap around */
  599.                 hiscnt = 0;
  600.             else
  601.                 ++hiscnt;
  602.             }
  603.             if (hiscnt < 0 || history[histype][hiscnt] == NULL)
  604.             {
  605.             hiscnt = i;
  606.             break;
  607.             }
  608.             if ((c != K_UP && c != K_DOWN) || hiscnt == i ||
  609.                 STRNCMP(history[histype][hiscnt],
  610.                             lookfor, (size_t)j) == 0)
  611.             break;
  612.         }
  613.  
  614.         if (hiscnt != i)    /* jumped to other entry */
  615.         {
  616.             vim_free(ccline.cmdbuff);
  617.             if (hiscnt == hislen)
  618.             p = lookfor;    /* back to the old one */
  619.             else
  620.             p = history[histype][hiscnt];
  621.  
  622.             alloc_cmdbuff((int)STRLEN(p));
  623.             if (ccline.cmdbuff == NULL)
  624.             goto returncmd;
  625.             STRCPY(ccline.cmdbuff, p);
  626.  
  627.             ccline.cmdpos = ccline.cmdlen = STRLEN(ccline.cmdbuff);
  628.             redrawcmd();
  629.             goto cmdline_changed;
  630.         }
  631.         beep_flush();
  632.         goto cmdline_not_changed;
  633.  
  634.     case Ctrl('V'):
  635.     case Ctrl('Q'):
  636. #ifdef USE_MOUSE
  637.         ignore_drag_release = TRUE;
  638. #endif
  639.         putcmdline('^');
  640.         c = get_literal();        /* get next (two) character(s) */
  641.         do_abbr = FALSE;        /* don't do abbreviation now */
  642.         break;
  643.  
  644. #ifdef DIGRAPHS
  645.     case Ctrl('K'):
  646. #ifdef USE_MOUSE
  647.         ignore_drag_release = TRUE;
  648. #endif
  649.         putcmdline('?');
  650. #ifdef USE_GUI_WIN32
  651.         dont_scroll = TRUE;        /* disallow scrolling here */
  652. #endif
  653.         ++no_mapping;
  654.         ++allow_keys;
  655.         c = vgetc();
  656.         --no_mapping;
  657.         --allow_keys;
  658.         if (c != ESC)            /* ESC cancels CTRL-K */
  659.         {
  660.             if (IS_SPECIAL(c))        /* insert special key code */
  661.             break;
  662.             if (charsize(c) == 1)
  663.             putcmdline(c);
  664.             ++no_mapping;
  665.             ++allow_keys;
  666.             cc = vgetc();
  667.             --no_mapping;
  668.             --allow_keys;
  669.             if (cc != ESC)        /* ESC cancels CTRL-K */
  670.             {
  671.             c = getdigraph(c, cc, TRUE);
  672.             break;
  673.             }
  674.         }
  675.         redrawcmd();
  676.         goto cmdline_not_changed;
  677. #endif /* DIGRAPHS */
  678.  
  679. #ifdef RIGHTLEFT
  680.     case Ctrl('_'):        /* CTRL-_: switch language mode */
  681. #ifdef FKMAP
  682.         if (p_altkeymap)
  683.         {
  684.             cmd_fkmap = !cmd_fkmap;
  685.             if (cmd_fkmap)    /* in Farsi always in Insert mode */
  686.             ccline.overstrike = FALSE;
  687.         }
  688.         else                /* Hebrew is default */
  689. #endif
  690.             cmd_hkmap = !cmd_hkmap;
  691.         goto cmdline_not_changed;
  692. #endif
  693.  
  694.     default:
  695. #ifdef UNIX
  696.         if (c == intr_char)
  697.         {
  698.             gotesc = TRUE;    /* will free ccline.cmdbuff after
  699.                        putting it in history */
  700.             goto returncmd;    /* back to cmd mode */
  701.         }
  702. #endif
  703.         /*
  704.          * Normal character with no special meaning.  Just set mod_mask
  705.          * to 0x0 so that typing Shift-Space in the GUI doesn't enter
  706.          * the string <S-Space>.  This should only happen after ^V.
  707.          */
  708.         if (!IS_SPECIAL(c))
  709.             mod_mask = 0x0;
  710.         break;
  711.     }
  712.  
  713.     /* we come here if we have a normal character */
  714.  
  715.     if (do_abbr && (IS_SPECIAL(c) || !vim_iswordc(c)) && ccheck_abbr(c))
  716.         goto cmdline_changed;
  717.  
  718.     /*
  719.      * put the character in the command line
  720.      */
  721.     if (IS_SPECIAL(c) || mod_mask != 0x0)
  722.         put_on_cmdline(get_special_key_name(c, mod_mask), -1, TRUE);
  723.     else
  724.     {
  725.         IObuff[0] = c;
  726.         put_on_cmdline(IObuff, 1, TRUE);
  727.     }
  728.     goto cmdline_changed;
  729.  
  730. /*
  731.  * This part implements incremental searches for "/" and "?"
  732.  * Jump to cmdline_not_changed when a character has been read but the command
  733.  * line did not change. Then we only search and redraw if something changed in
  734.  * the past.
  735.  * Jump to cmdline_changed when the command line did change.
  736.  * (Sorry for the goto's, I know it is ugly).
  737.  */
  738. cmdline_not_changed:
  739. #ifdef EXTRA_SEARCH
  740.     if (!incsearch_postponed)
  741.         continue;
  742. #endif
  743.  
  744. cmdline_changed:
  745. #ifdef EXTRA_SEARCH
  746.     if (p_is && (firstc == '/' || firstc == '?'))
  747.     {
  748.         /* if there is a character waiting, search and redraw later */
  749.         if (char_avail())
  750.         {
  751.         incsearch_postponed = TRUE;
  752.         continue;
  753.         }
  754.         incsearch_postponed = FALSE;
  755.         curwin->w_cursor = old_cursor;  /* start at old position */
  756.  
  757.         /* If there is no command line, don't do anything */
  758.         if (ccline.cmdlen == 0)
  759.         i = 0;
  760.         else
  761.         {
  762.         ccline.cmdbuff[ccline.cmdlen] = NUL;
  763.         emsg_off = TRUE;    /* So it doesn't beep if bad expr */
  764.         i = do_search(NULL, firstc, ccline.cmdbuff, count,
  765.                       SEARCH_KEEP + SEARCH_OPT + SEARCH_NOOF);
  766.         emsg_off = FALSE;
  767.         }
  768.         if (i)
  769.         highlight_match = TRUE;        /* highlight position */
  770.         else
  771.         highlight_match = FALSE;        /* don't highlight */
  772.  
  773.         /* first restore the old curwin values, so the screen is
  774.          * positioned in the same way as the actual search command */
  775.         curwin->w_leftcol = old_leftcol;
  776.         curwin->w_topline = old_topline;
  777.         curwin->w_botline = old_botline;
  778.         update_topline();
  779.         /*
  780.          * First move cursor to end of match, then to start.  This moves
  781.          * the whole match onto the screen when 'nowrap' is set.
  782.          */
  783.         curwin->w_cursor.col += search_match_len;
  784.         validate_cursor();
  785.         curwin->w_cursor.col -= search_match_len;
  786.         validate_cursor();
  787.  
  788.         update_screen(NOT_VALID);
  789.         redrawcmdline();
  790.         did_incsearch = TRUE;
  791.     }
  792. #endif
  793.     }
  794.  
  795. returncmd:
  796.  
  797. #ifdef FKMAP
  798.     cmd_fkmap = 0;
  799. #endif
  800.  
  801. #ifdef EXTRA_SEARCH
  802.     if (did_incsearch)
  803.     {
  804.     curwin->w_cursor = old_cursor;
  805.     curwin->w_curswant = old_curswant;
  806.     curwin->w_leftcol = old_leftcol;
  807.     curwin->w_topline = old_topline;
  808.     curwin->w_botline = old_botline;
  809.     highlight_match = FALSE;
  810.     validate_cursor();    /* needed for TAB */
  811.     redraw_later(NOT_VALID);
  812.     }
  813. #endif
  814.  
  815.     if (ccline.cmdbuff != NULL)
  816.     {
  817.     /*
  818.      * Put line in history buffer (":" and "=" only when it was typed).
  819.      */
  820.     ccline.cmdbuff[ccline.cmdlen] = NUL;
  821.     if (ccline.cmdlen && firstc &&
  822.                    (some_key_typed || histype == HIST_SEARCH))
  823.     {
  824.         add_to_history(histype, ccline.cmdbuff);
  825.         if (firstc == ':')
  826.         {
  827.         vim_free(new_last_cmdline);
  828.         new_last_cmdline = vim_strsave(ccline.cmdbuff);
  829.         }
  830.     }
  831.  
  832.     if (gotesc)        /* abandon command line */
  833.     {
  834.         vim_free(ccline.cmdbuff);
  835.         ccline.cmdbuff = NULL;
  836.         MSG("");
  837.         redraw_cmdline = TRUE;
  838.     }
  839.     }
  840.  
  841.     /*
  842.      * If the screen was shifted up, redraw the whole screen (later).
  843.      * If the line is too long, clear it, so ruler and shown command do
  844.      * not get printed in the middle of it.
  845.      */
  846.     msg_check();
  847.     msg_scroll = save_msg_scroll;
  848.     redir_off = FALSE;
  849.  
  850.     State = save_State;
  851. #ifdef USE_MOUSE
  852.     setmouse();
  853. #endif
  854.  
  855.     return ccline.cmdbuff;
  856. }
  857.  
  858. /*
  859.  * Get an Ex command line for the ":" command.
  860.  */
  861. /* ARGSUSED */
  862.     char_u *
  863. getexline(c, dummy, indent)
  864.     int        c;        /* normally ':', NUL for ":append" */
  865.     void    *dummy;        /* cookie not used */
  866.     int        indent;        /* indent for inside conditionals */
  867. {
  868.     return getcmdline(c, 1L, indent);
  869. }
  870.  
  871. /*
  872.  * Get an Ex command line for Ex mode.
  873.  * In Ex mode we only use the OS supplied line editing features and no
  874.  * mappings or abbreviations.
  875.  */
  876. /* ARGSUSED */
  877.     char_u *
  878. getexmodeline(c, dummy, indent)
  879.     int        c;        /* normally ':', NUL for ":append" */
  880.     void    *dummy;        /* cookie not used */
  881.     int        indent;        /* indent for inside conditionals */
  882. {
  883.     struct growarray    line_ga;
  884.     int            len;
  885.     int            off = 0;
  886.     char_u        *p;
  887.     int            finished = FALSE;
  888. #if defined(USE_GUI) || defined(NO_COOKED_INPUT)
  889.     int            startcol = 0;
  890.     int            c1;
  891.     int            escaped = FALSE;    /* CTRL-V typed */
  892. #endif
  893.  
  894.     /* always start in column 0; write a newline if necessary */
  895.     compute_cmdrow();
  896.     if (msg_col)
  897.     msg_putchar('\n');
  898.     if (c == ':')
  899.     {
  900.     msg_putchar(':');
  901.     while (indent-- > 0)
  902.         msg_putchar(' ');
  903. #if defined(USE_GUI) || defined(NO_COOKED_INPUT)
  904.     startcol = msg_col;
  905. #endif
  906.     }
  907.  
  908.     ga_init(&line_ga);
  909.     line_ga.ga_itemsize = 1;
  910.     line_ga.ga_growsize = 30;
  911.  
  912.     /*
  913.      * Get the line, one character at a time.
  914.      */
  915.     got_int = FALSE;
  916.     while (!got_int && !finished)
  917.     {
  918.     if (ga_grow(&line_ga, 40) == FAIL)
  919.         break;
  920.     p = (char_u *)line_ga.ga_data + line_ga.ga_len;
  921.  
  922.     /* Get one character (inchar gets a third of maxlen characters!) */
  923.     len = inchar(p + off, 3, -1L);
  924.     if (len < 0)
  925.         continue;        /* end of input script reached */
  926.     /* for a special character, we need at least three characters */
  927.     if ((*p == K_SPECIAL || *p == CSI) && off + len < 3)
  928.     {
  929.         off += len;
  930.         continue;
  931.     }
  932.     len += off;
  933.     off = 0;
  934.  
  935.     /*
  936.      * When using the GUI, and for systems that don't have cooked input,
  937.      * handle line editing here.
  938.      */
  939. #if defined(USE_GUI) || defined(NO_COOKED_INPUT)
  940. # ifndef NO_COOKED_INPUT
  941.     if (gui.in_use)
  942. # endif
  943.     {
  944.         if (got_int)
  945.         {
  946.         msg_putchar('\n');
  947.         break;
  948.         }
  949.  
  950.         while (len > 0)
  951.         {
  952.         c1 = *p++;
  953.         --len;
  954. # ifndef NO_COOKED_INPUT
  955.         if ((c1 == K_SPECIAL || c1 == CSI) && len >= 2)
  956. # else
  957. #  ifdef USE_GUI
  958.         if ((c1 == K_SPECIAL || (c1 == CSI && gui.in_use)) && len >= 2)
  959. #  else
  960.         if (c1 == K_SPECIAL && len >= 2)
  961. #  endif
  962. # endif
  963.         {
  964.             c1 = TO_SPECIAL(p[0], p[1]);
  965.             p += 2;
  966.             len -= 2;
  967.         }
  968.  
  969.         if (!escaped)
  970.         {
  971.             if (c1 == BS || c1 == K_BS || c1 == DEL || c1 == K_DEL)
  972.             {
  973.             if (line_ga.ga_len > 0)
  974.             {
  975.                 msg_putchar('\b');
  976.                 msg_putchar(' ');
  977.                 msg_putchar('\b');
  978.                 --line_ga.ga_len;
  979.                 ++line_ga.ga_room;
  980.             }
  981.             continue;
  982.             }
  983.  
  984.             if (c1 == Ctrl('U'))
  985.             {
  986.             msg_col = startcol;
  987.             msg_clr_eos();
  988.             line_ga.ga_room += line_ga.ga_len;
  989.             line_ga.ga_len = 0;
  990.             continue;
  991.             }
  992.  
  993.             if (c1 == Ctrl('V'))
  994.             {
  995.             escaped = TRUE;
  996.             continue;
  997.             }
  998.         }
  999.  
  1000.         ((char_u *)line_ga.ga_data)[line_ga.ga_len] = c1;
  1001.         if (c1 == '\r')
  1002.             msg_putchar('\n');
  1003.         else
  1004.             msg_putchar(c1);
  1005.         ++line_ga.ga_len;
  1006.         --line_ga.ga_room;
  1007.         escaped = FALSE;
  1008.         }
  1009.         windgoto(msg_row, msg_col);
  1010.     }
  1011. # ifndef NO_COOKED_INPUT
  1012.     else
  1013. # endif
  1014. #endif
  1015. #ifndef NO_COOKED_INPUT
  1016.     {
  1017.         line_ga.ga_len += len;
  1018.         line_ga.ga_room -= len;
  1019.     }
  1020. #endif
  1021.     p = (char_u *)(line_ga.ga_data) + line_ga.ga_len;
  1022.     while (line_ga.ga_len && (p[-1] == '\n' || p[-1] == '\r'))
  1023.     {
  1024.         finished = TRUE;
  1025.         --line_ga.ga_len;
  1026.         --p;
  1027.         *p = NUL;
  1028.     }
  1029.     }
  1030.  
  1031.     /* note that cursor has moved, because of the echoed <CR> */
  1032.     screen_down();
  1033.     /* make following messages go to the next line */
  1034.     msg_didout = FALSE;
  1035.     msg_col = 0;
  1036.     if (msg_row < Rows - 1)
  1037.     ++msg_row;
  1038.     emsg_on_display = FALSE;        /* don't want ui_delay() */
  1039.  
  1040.     if (got_int)
  1041.     ga_clear(&line_ga);
  1042.  
  1043.     return (char_u *)line_ga.ga_data;
  1044. }
  1045.  
  1046. #ifdef USE_GUI
  1047. /*
  1048.  * Return TRUE if ccline.overstrike is on.
  1049.  */
  1050.     int
  1051. cmdline_overstrike()
  1052. {
  1053.     return ccline.overstrike;
  1054. }
  1055.  
  1056. /*
  1057.  * Return TRUE if the cursor is at the end of the cmdline.
  1058.  */
  1059.     int
  1060. cmdline_at_end()
  1061. {
  1062.     return (ccline.cmdpos >= ccline.cmdlen);
  1063. }
  1064. #endif
  1065.  
  1066. /*
  1067.  * Allocate a new command line buffer.
  1068.  * Assigns the new buffer to ccline.cmdbuff and ccline.cmdbufflen.
  1069.  * Returns the new value of ccline.cmdbuff and ccline.cmdbufflen.
  1070.  */
  1071.     static void
  1072. alloc_cmdbuff(len)
  1073.     int        len;
  1074. {
  1075.     /*
  1076.      * give some extra space to avoid having to allocate all the time
  1077.      */
  1078.     if (len < 80)
  1079.     len = 100;
  1080.     else
  1081.     len += 20;
  1082.  
  1083.     ccline.cmdbuff = alloc(len);    /* caller should check for out-of-memory */
  1084.     ccline.cmdbufflen = len;
  1085. }
  1086.  
  1087. /*
  1088.  * Re-allocate the command line to length len + something extra.
  1089.  * return FAIL for failure, OK otherwise
  1090.  */
  1091.     static int
  1092. realloc_cmdbuff(len)
  1093.     int        len;
  1094. {
  1095.     char_u    *p;
  1096.  
  1097.     p = ccline.cmdbuff;
  1098.     alloc_cmdbuff(len);            /* will get some more */
  1099.     if (ccline.cmdbuff == NULL)        /* out of memory */
  1100.     {
  1101.     ccline.cmdbuff = p;        /* keep the old one */
  1102.     return FAIL;
  1103.     }
  1104.     vim_memmove(ccline.cmdbuff, p, (size_t)ccline.cmdlen);
  1105.     vim_free(p);
  1106.     return OK;
  1107. }
  1108.  
  1109. /*
  1110.  * put a character on the command line.
  1111.  * Used for CTRL-V and CTRL-K
  1112.  */
  1113.     static void
  1114. putcmdline(c)
  1115.     int        c;
  1116. {
  1117.     char_u  buf[1];
  1118.  
  1119.     buf[0] = c;
  1120.     msg_outtrans_len(buf, 1);
  1121.     msg_outtrans_len(ccline.cmdbuff + ccline.cmdpos,
  1122.                            ccline.cmdlen - ccline.cmdpos);
  1123.     cursorcmd();
  1124. }
  1125.  
  1126. /*
  1127.  * Put the given string, of the given length, onto the command line.
  1128.  * If len is -1, then STRLEN() is used to calculate the length.
  1129.  * If 'redraw' is TRUE then the new part of the command line, and the remaining
  1130.  * part will be redrawn, otherwise it will not.  If this function is called
  1131.  * twice in a row, then 'redraw' should be FALSE and redrawcmd() should be
  1132.  * called afterwards.
  1133.  */
  1134.     int
  1135. put_on_cmdline(str, len, redraw)
  1136.     char_u  *str;
  1137.     int        len;
  1138.     int        redraw;
  1139. {
  1140.     int        i;
  1141.  
  1142.     if (len < 0)
  1143.     len = STRLEN(str);
  1144.  
  1145.     /* Check if ccline.cmdbuff needs to be longer */
  1146.     if (ccline.cmdlen + len + 1 >= ccline.cmdbufflen)
  1147.     i = realloc_cmdbuff(ccline.cmdlen + len);
  1148.     else
  1149.     i = OK;
  1150.     if (i == OK)
  1151.     {
  1152.     if (!ccline.overstrike)
  1153.     {
  1154.         vim_memmove(ccline.cmdbuff + ccline.cmdpos + len,
  1155.                            ccline.cmdbuff + ccline.cmdpos,
  1156.                      (size_t)(ccline.cmdlen - ccline.cmdpos));
  1157.         ccline.cmdlen += len;
  1158.     }
  1159.     else if (ccline.cmdpos + len > ccline.cmdlen)
  1160.         ccline.cmdlen = ccline.cmdpos + len;
  1161.     vim_memmove(ccline.cmdbuff + ccline.cmdpos, str, (size_t)len);
  1162.     if (redraw)
  1163.         msg_outtrans_len(ccline.cmdbuff + ccline.cmdpos,
  1164.                            ccline.cmdlen - ccline.cmdpos);
  1165. #ifdef FKMAP
  1166.     /*
  1167.      ** If we are in Farsi command mode, the character input must be in
  1168.      ** insert mode. So do not advance the cmdpos.
  1169.      */
  1170.     if (!cmd_fkmap)
  1171. #endif
  1172.     {
  1173.         ccline.cmdpos += len;
  1174.         while (len--)
  1175.         ccline.cmdspos += charsize(str[len]);
  1176.     }
  1177.     }
  1178.     if (redraw)
  1179.     msg_check();
  1180.     return i;
  1181. }
  1182.  
  1183. /*
  1184.  * this fuction is called when the screen size changes and with incremental
  1185.  * search
  1186.  */
  1187.     void
  1188. redrawcmdline()
  1189. {
  1190.     msg_scrolled = 0;
  1191.     need_wait_return = FALSE;
  1192.     compute_cmdrow();
  1193.     redrawcmd();
  1194.     cursorcmd();
  1195. }
  1196.  
  1197. /*
  1198.  * Redraw what is currently on the command line.
  1199.  */
  1200.     static void
  1201. redrawcmd()
  1202. {
  1203.     int        i;
  1204.  
  1205.     msg_start();
  1206.     if (ccline.cmdfirstc)
  1207.     msg_putchar(ccline.cmdfirstc);
  1208.     for (i = ccline.cmdindent; i > 0; --i)
  1209.     msg_putchar(' ');
  1210.     msg_outtrans_len(ccline.cmdbuff, ccline.cmdlen);
  1211.     msg_clr_eos();
  1212.  
  1213.     if (ccline.cmdfirstc)
  1214.     ccline.cmdspos = 1 + ccline.cmdindent;
  1215.     else
  1216.     ccline.cmdspos = 0 + ccline.cmdindent;
  1217.     for (i = 0; i < ccline.cmdlen && i < ccline.cmdpos; ++i)
  1218.     ccline.cmdspos += charsize(ccline.cmdbuff[i]);
  1219.     /*
  1220.      * An emsg() before may have set msg_scroll. This is used in normal mode,
  1221.      * in cmdline mode we can reset them now.
  1222.      */
  1223.     msg_scroll = FALSE;        /* next message overwrites cmdline */
  1224.     
  1225.     /* Typing ':' at the more prompt may set skip_redraw.  We don't want this
  1226.      * in cmdline mode */
  1227.     skip_redraw = FALSE;
  1228. }
  1229.  
  1230.     void
  1231. compute_cmdrow()
  1232. {
  1233.     if (exmode_active)
  1234.     cmdline_row = Rows - 1;
  1235.     else
  1236.     cmdline_row = lastwin->w_winpos + lastwin->w_height +
  1237.                     lastwin->w_status_height;
  1238. }
  1239.  
  1240.     static void
  1241. cursorcmd()
  1242. {
  1243.     msg_row = cmdline_row + (ccline.cmdspos / (int)Columns);
  1244.     msg_col = ccline.cmdspos % (int)Columns;
  1245.     if (msg_row >= Rows)
  1246.     msg_row = Rows - 1;
  1247.     windgoto(msg_row, msg_col);
  1248. }
  1249.  
  1250.     void
  1251. gotocmdline(clr)
  1252.     int            clr;
  1253. {
  1254.     msg_start();
  1255.     if (clr)            /* clear the bottom line(s) */
  1256.     msg_clr_eos();        /* will reset clear_cmdline */
  1257.     windgoto(cmdline_row, 0);
  1258. }
  1259.  
  1260. /*
  1261.  * Check the word in front of the cursor for an abbreviation.
  1262.  * Called when the non-id character "c" has been entered.
  1263.  * When an abbreviation is recognized it is removed from the text with
  1264.  * backspaces and the replacement string is inserted, followed by "c".
  1265.  */
  1266.     static int
  1267. ccheck_abbr(c)
  1268.     int c;
  1269. {
  1270.     if (p_paste || no_abbr)        /* no abbreviations or in paste mode */
  1271.     return FALSE;
  1272.  
  1273.     return check_abbr(c, ccline.cmdbuff, ccline.cmdpos, 0);
  1274. }
  1275.  
  1276. /*
  1277.  * Return FAIL if this is not an appropriate context in which to do
  1278.  * completion of anything, return OK if it is (even if there are no matches).
  1279.  * For the caller, this means that the character is just passed through like a
  1280.  * normal character (instead of being expanded).  This allows :s/^I^D etc.
  1281.  */
  1282.     static int
  1283. nextwild(type)
  1284.     int        type;
  1285. {
  1286.     int        i;
  1287.     char_u  *p1;
  1288.     char_u  *p2;
  1289.     int        oldlen;
  1290.     int        difflen;
  1291.     int        v;
  1292.  
  1293.     if (cmd_numfiles == -1)
  1294.     set_expand_context();
  1295.     if (expand_context == EXPAND_UNSUCCESSFUL)
  1296.     {
  1297.     beep_flush();
  1298.     return OK;  /* Something illegal on command line */
  1299.     }
  1300.     if (expand_context == EXPAND_NOTHING)
  1301.     {
  1302.     /* Caller can use the character as a normal char instead */
  1303.     return FAIL;
  1304.     }
  1305.     expand_interactively = TRUE;
  1306.  
  1307.     MSG_PUTS("...");        /* show that we are busy */
  1308.     out_flush();
  1309.  
  1310.     i = expand_pattern - ccline.cmdbuff;
  1311.     oldlen = ccline.cmdpos - i;
  1312.  
  1313.     if (type == WILD_NEXT || type == WILD_PREV)
  1314.     {
  1315.     /*
  1316.      * Get next/previous match for a previous expanded pattern.
  1317.      */
  1318.     p2 = ExpandOne(NULL, NULL, 0, type);
  1319.     }
  1320.     else
  1321.     {
  1322.     /*
  1323.      * Translate string into pattern and expand it.
  1324.      */
  1325.     if ((p1 = addstar(&ccline.cmdbuff[i], oldlen)) == NULL)
  1326.         p2 = NULL;
  1327.     else
  1328.     {
  1329.         p2 = ExpandOne(p1, vim_strnsave(&ccline.cmdbuff[i], oldlen),
  1330.                              WILD_HOME_REPLACE, type);
  1331.         vim_free(p1);
  1332.     }
  1333.     }
  1334.  
  1335.     if (p2 != NULL)
  1336.     {
  1337.     if (ccline.cmdlen + (difflen = STRLEN(p2) - oldlen) >
  1338.                             ccline.cmdbufflen - 4)
  1339.         v = realloc_cmdbuff(ccline.cmdlen + difflen);
  1340.     else
  1341.         v = OK;
  1342.     if (v == OK)
  1343.     {
  1344.         vim_strncpy(&ccline.cmdbuff[ccline.cmdpos + difflen],
  1345.                            &ccline.cmdbuff[ccline.cmdpos],
  1346.             ccline.cmdlen - ccline.cmdpos);
  1347.         STRNCPY(&ccline.cmdbuff[i], p2, STRLEN(p2));
  1348.         ccline.cmdlen += difflen;
  1349.         ccline.cmdpos += difflen;
  1350.     }
  1351.     vim_free(p2);
  1352.     }
  1353.  
  1354.     redrawcmd();
  1355.     if (cmd_numfiles <= 0 && p2 == NULL)
  1356.     beep_flush();
  1357.     else if (cmd_numfiles == 1)
  1358.     (void)ExpandOne(NULL, NULL, 0, WILD_FREE);  /* free expanded pattern */
  1359.  
  1360.     expand_interactively = FALSE;        /* reset for next call */
  1361.     return OK;
  1362. }
  1363.  
  1364. #define MAXSUFLEN 30        /* maximum length of a file suffix */
  1365.  
  1366. /*
  1367.  * Do wildcard expansion on the string 'str'.
  1368.  * Return a pointer to alloced memory containing the new string.
  1369.  * Return NULL for failure.
  1370.  *
  1371.  * mode = WILD_FREE:        just free previously expanded matches
  1372.  * mode = WILD_EXPAND_FREE: normal expansion, do not keep matches
  1373.  * mode = WILD_EXPAND_KEEP: normal expansion, keep matches
  1374.  * mode = WILD_NEXT:        use next match in multiple match, wrap to first
  1375.  * mode = WILD_PREV:        use previous match in multiple match, wrap to first
  1376.  * mode = WILD_ALL:        return all matches concatenated
  1377.  * mode = WILD_LONGEST:        return longest matched part
  1378.  *
  1379.  * options = WILD_LIST_NOTFOUND:    list entries without a match
  1380.  * options = WILD_HOME_REPLACE:        do home_replace() for buffer names
  1381.  * options = WILD_USE_NL:        Use '\n' for WILD_ALL
  1382.  */
  1383.     char_u *
  1384. ExpandOne(str, orig, options, mode)
  1385.     char_u  *str;
  1386.     char_u  *orig;        /* original string which is expanded */
  1387.     int        options;
  1388.     int        mode;
  1389. {
  1390.     char_u    *ss = NULL;
  1391.     static char_u **cmd_files = NULL;    /* list of input files */
  1392.     static int    findex;
  1393.     static char_u *orig_save = NULL;    /* kept value of orig */
  1394.     int        i, j;
  1395.     int        non_suf_match;        /* number without matching suffix */
  1396.     long_u    len;
  1397.     char_u    *setsuf;
  1398.     int        fnamelen, setsuflen;
  1399.     char_u    suf_buf[MAXSUFLEN];
  1400.     char_u    *p;
  1401.  
  1402. /*
  1403.  * first handle the case of using an old match
  1404.  */
  1405.     if (mode == WILD_NEXT || mode == WILD_PREV)
  1406.     {
  1407.     if (cmd_numfiles > 0)
  1408.     {
  1409.         if (mode == WILD_PREV)
  1410.         {
  1411.         if (findex == -1)
  1412.             findex = cmd_numfiles;
  1413.         --findex;
  1414.         }
  1415.         else    /* mode == WILD_NEXT */
  1416.         ++findex;
  1417.  
  1418.         /*
  1419.          * When wrapping around, return the original string, set findex to
  1420.          * -1.
  1421.          */
  1422.         if (findex < 0)
  1423.         {
  1424.         if (orig_save == NULL)
  1425.             findex = cmd_numfiles - 1;
  1426.         else
  1427.             findex = -1;
  1428.         }
  1429.         if (findex >= cmd_numfiles)
  1430.         {
  1431.         if (orig_save == NULL)
  1432.             findex = 0;
  1433.         else
  1434.             findex = -1;
  1435.         }
  1436.         if (findex == -1)
  1437.         return vim_strsave(orig_save);
  1438.         return vim_strsave(cmd_files[findex]);
  1439.     }
  1440.     else
  1441.         return NULL;
  1442.     }
  1443.  
  1444. /* free old names */
  1445.     if (cmd_numfiles != -1 && mode != WILD_ALL && mode != WILD_LONGEST)
  1446.     {
  1447.     FreeWild(cmd_numfiles, cmd_files);
  1448.     cmd_numfiles = -1;
  1449.     vim_free(orig_save);
  1450.     orig_save = NULL;
  1451.     }
  1452.     findex = 0;
  1453.  
  1454.     if (mode == WILD_FREE)    /* only release file name */
  1455.     return NULL;
  1456.  
  1457.     if (cmd_numfiles == -1)
  1458.     {
  1459.     vim_free(orig_save);
  1460.     orig_save = orig;
  1461.  
  1462.     if (ExpandFromContext(str, &cmd_numfiles, &cmd_files, FALSE,
  1463.                                  options) == FAIL)
  1464.         /* error: do nothing */;
  1465.     else if (cmd_numfiles == 0)
  1466.     {
  1467.         if (!expand_interactively)
  1468.         emsg2(e_nomatch2, str);
  1469.     }
  1470.     else
  1471.     {
  1472.         /*
  1473.          * May change home directory back to "~"
  1474.          */
  1475.         if (options & WILD_HOME_REPLACE)
  1476.         tilde_replace(str, cmd_numfiles, cmd_files);
  1477.  
  1478.         /*
  1479.          * Insert backslashes into a file name before a space, \, %, # and
  1480.          * wildmatch characters, except '~'.
  1481.          */
  1482.         if (expand_interactively &&
  1483.             (expand_context == EXPAND_FILES ||
  1484.              expand_context == EXPAND_BUFFERS ||
  1485.              expand_context == EXPAND_DIRECTORIES))
  1486.         {
  1487.         for (i = 0; i < cmd_numfiles; ++i)
  1488.         {
  1489.             /* for ":set path=" we need to escape spaces twice */
  1490.             if (expand_set_path)
  1491.             {
  1492.             p = vim_strsave_escaped(cmd_files[i], (char_u *)" ");
  1493.             if (p != NULL)
  1494.             {
  1495.                 vim_free(cmd_files[i]);
  1496.                 cmd_files[i] = p;
  1497. #if defined(BACKSLASH_IN_FILENAME) || defined(COLON_AS_PATHSEP)
  1498.                 p = vim_strsave_escaped(cmd_files[i],
  1499.                                    (char_u *)" ");
  1500.                 if (p != NULL)
  1501.                 {
  1502.                 vim_free(cmd_files[i]);
  1503.                 cmd_files[i] = p;
  1504.                 }
  1505. #endif
  1506.             }
  1507.             }
  1508.             p = vim_strsave_escaped(cmd_files[i],
  1509. #ifdef BACKSLASH_IN_FILENAME
  1510.                             (char_u *)" *?[{`$%#"
  1511. #else
  1512. # ifdef COLON_AS_PATHSEP
  1513.                             (char_u *)" *?[{`$%#/"
  1514. # else
  1515.                             (char_u *)" *?[{`$\\%#"
  1516. # endif
  1517. #endif
  1518.                                         );
  1519.             if (p != NULL)
  1520.             {
  1521.             vim_free(cmd_files[i]);
  1522.             cmd_files[i] = p;
  1523.             }
  1524.         }
  1525.         expand_set_path = FALSE;
  1526.         }
  1527.  
  1528.         if (mode != WILD_ALL && mode != WILD_LONGEST)
  1529.         {
  1530.         non_suf_match = 1;
  1531.         if (cmd_numfiles > 1)    /* more than one match; check suffix */
  1532.         {
  1533.             non_suf_match = 0;
  1534.             for (i = 0; i < cmd_numfiles; ++i)
  1535.             {
  1536.             fnamelen = STRLEN(cmd_files[i]);
  1537.             setsuflen = 0;
  1538.             for (setsuf = p_su; *setsuf; )
  1539.             {
  1540.                 setsuflen = copy_option_part(&setsuf, suf_buf,
  1541.                                   MAXSUFLEN, ".,");
  1542.                 if (fnamelen >= setsuflen && STRNCMP(suf_buf,
  1543.                       cmd_files[i] + fnamelen - setsuflen,
  1544.                               (size_t)setsuflen) == 0)
  1545.                 break;
  1546.                 setsuflen = 0;
  1547.             }
  1548.             if (setsuflen)        /* suffix matched: ignore file */
  1549.                 continue;
  1550.             /*
  1551.              * Move the name without matching suffix to the front
  1552.              * of the list.  This makes CTRL-N work nice.
  1553.              */
  1554.             p = cmd_files[i];
  1555.             for (j = i; j > non_suf_match; --j)
  1556.                 cmd_files[j] = cmd_files[j - 1];
  1557.             cmd_files[non_suf_match++] = p;
  1558.             }
  1559.         }
  1560.         if (non_suf_match != 1)
  1561.         {
  1562.             /* Can we ever get here unless it's while expanding
  1563.              * interactively?  If not, we can get rid of this all
  1564.              * together. Don't really want to wait for this message
  1565.              * (and possibly have to hit return to continue!).
  1566.              */
  1567.             if (!expand_interactively)
  1568.             emsg(e_toomany);
  1569.             else
  1570.             beep_flush();
  1571.         }
  1572.         if (!(non_suf_match != 1 && mode == WILD_EXPAND_FREE))
  1573.             ss = vim_strsave(cmd_files[0]);
  1574.         }
  1575.     }
  1576.     }
  1577.  
  1578.     /* Find longest common part */
  1579.     if (mode == WILD_LONGEST && cmd_numfiles > 0)
  1580.     {
  1581.     for (len = 0; cmd_files[0][len]; ++len)
  1582.     {
  1583.         for (i = 0; i < cmd_numfiles; ++i)
  1584.         {
  1585. #ifdef CASE_INSENSITIVE_FILENAME
  1586.         if (expand_context == EXPAND_DIRECTORIES
  1587.             || expand_context == EXPAND_FILES
  1588.             || expand_context == EXPAND_BUFFERS)
  1589.         {
  1590.             if (TO_LOWER(cmd_files[i][len]) !=
  1591.                            TO_LOWER(cmd_files[0][len]))
  1592.             break;
  1593.         }
  1594.         else
  1595. #endif
  1596.              if (cmd_files[i][len] != cmd_files[0][len])
  1597.             break;
  1598.         }
  1599.         if (i < cmd_numfiles)
  1600.         {
  1601.         vim_beep();
  1602.         break;
  1603.         }
  1604.     }
  1605.     ss = alloc((unsigned)len + 1);
  1606.     if (ss)
  1607.     {
  1608.         STRNCPY(ss, cmd_files[0], len);
  1609.         ss[len] = NUL;
  1610.     }
  1611.     findex = -1;                /* next p_wc gets first one */
  1612.     }
  1613.  
  1614.     /* Concatenate all matching names */
  1615.     if (mode == WILD_ALL && cmd_numfiles > 0)
  1616.     {
  1617.     len = 0;
  1618.     for (i = 0; i < cmd_numfiles; ++i)
  1619.         len += STRLEN(cmd_files[i]) + 1;
  1620.     ss = lalloc(len, TRUE);
  1621.     if (ss != NULL)
  1622.     {
  1623.         *ss = NUL;
  1624.         for (i = 0; i < cmd_numfiles; ++i)
  1625.         {
  1626.         STRCAT(ss, cmd_files[i]);
  1627.         if (i != cmd_numfiles - 1)
  1628.             STRCAT(ss, (options & WILD_USE_NL) ? "\n" : " ");
  1629.         }
  1630.     }
  1631.     }
  1632.  
  1633.     if (mode == WILD_EXPAND_FREE || mode == WILD_ALL)
  1634.     {
  1635.     FreeWild(cmd_numfiles, cmd_files);
  1636.     cmd_numfiles = -1;
  1637.     }
  1638.  
  1639.     return ss;
  1640. }
  1641.  
  1642. /*
  1643.  * For each file name in files[num_files]:
  1644.  * If 'orig_pat' starts with "~/", replace the home directory with "~".
  1645.  */
  1646.     void
  1647. tilde_replace(orig_pat, num_files, files)
  1648.     char_u  *orig_pat;
  1649.     int        num_files;
  1650.     char_u  **files;
  1651. {
  1652.     int        i;
  1653.     char_u  *p;
  1654.  
  1655.     if (orig_pat[0] == '~' && vim_ispathsep(orig_pat[1]))
  1656.     {
  1657.     for (i = 0; i < num_files; ++i)
  1658.     {
  1659.         p = home_replace_save(NULL, files[i]);
  1660.         if (p != NULL)
  1661.         {
  1662.         vim_free(files[i]);
  1663.         files[i] = p;
  1664.         }
  1665.     }
  1666.     }
  1667. }
  1668.  
  1669. /*
  1670.  * show all matches for completion on the command line
  1671.  */
  1672.     static int
  1673. showmatches()
  1674. {
  1675.     char_u    *file_str;
  1676.     int        num_files;
  1677.     char_u    **files_found;
  1678.     int        i, j, k;
  1679.     int        maxlen;
  1680.     int        lines;
  1681.     int        columns;
  1682.     char_u    *p;
  1683.     int        lastlen;
  1684.     int        attr;
  1685.  
  1686.     set_expand_context();
  1687.     if (expand_context == EXPAND_UNSUCCESSFUL)
  1688.     {
  1689.     beep_flush();
  1690.     return OK;  /* Something illegal on command line */
  1691.     }
  1692.     if (expand_context == EXPAND_NOTHING)
  1693.     {
  1694.     /* Caller can use the character as a normal char instead */
  1695.     return FAIL;
  1696.     }
  1697.     expand_interactively = TRUE;
  1698.  
  1699.     /* add star to file name, or convert to regexp if not expanding files! */
  1700.     file_str = addstar(expand_pattern,
  1701.               (int)(ccline.cmdbuff + ccline.cmdpos - expand_pattern));
  1702.     if (file_str == NULL)
  1703.     {
  1704.     expand_interactively = FALSE;
  1705.     return OK;
  1706.     }
  1707.  
  1708.     msg_didany = FALSE;            /* lines_left will be set */
  1709.     msg_start();            /* prepare for paging */
  1710.     msg_putchar('\n');
  1711.     out_flush();
  1712.     cmdline_row = msg_row;
  1713.     msg_didany = FALSE;            /* lines_left will be set again */
  1714.     msg_start();            /* prepare for paging */
  1715.  
  1716.     /* find all files that match the description */
  1717.     if (ExpandFromContext(file_str, &num_files, &files_found, FALSE, 0) == FAIL)
  1718.     {
  1719.     num_files = 0;
  1720.     files_found = (char_u **)"";
  1721.     }
  1722.  
  1723.     /* find the length of the longest file name */
  1724.     maxlen = 0;
  1725.     for (i = 0; i < num_files; ++i)
  1726.     {
  1727.     if (expand_context == EXPAND_FILES || expand_context == EXPAND_BUFFERS)
  1728.     {
  1729.         home_replace(NULL, files_found[i], NameBuff, MAXPATHL);
  1730.         j = vim_strsize(NameBuff);
  1731.     }
  1732.     else
  1733.         j = vim_strsize(files_found[i]);
  1734.     if (j > maxlen)
  1735.         maxlen = j;
  1736.     }
  1737.  
  1738.     /* compute the number of columns and lines for the listing */
  1739.     maxlen += 2;    /* two spaces between file names */
  1740.     columns = ((int)Columns + 2) / maxlen;
  1741.     if (columns < 1)
  1742.     columns = 1;
  1743.     lines = (num_files + columns - 1) / columns;
  1744.  
  1745.     attr = highlight_attr[HLF_D];   /* find out highlighting for directories */
  1746.  
  1747.     /* list the files line by line */
  1748.     for (i = 0; i < lines; ++i)
  1749.     {
  1750.     lastlen = 999;
  1751.     for (k = i; k < num_files; k += lines)
  1752.     {
  1753.         for (j = maxlen - lastlen; --j >= 0; )
  1754.         msg_putchar(' ');
  1755.         if (expand_context == EXPAND_FILES ||
  1756.                          expand_context == EXPAND_BUFFERS)
  1757.         {
  1758.             /* highlight directories */
  1759.         j = (mch_isdir(files_found[k]));
  1760.         home_replace(NULL, files_found[k], NameBuff, MAXPATHL);
  1761.         p = NameBuff;
  1762.         }
  1763.         else
  1764.         {
  1765.         j = FALSE;
  1766.         p = files_found[k];
  1767.         }
  1768.         lastlen = msg_outtrans_attr(p, j ? attr : 0);
  1769.     }
  1770.     msg_clr_eos();
  1771.     msg_putchar('\n');
  1772.     out_flush();            /* show one line at a time */
  1773.     if (got_int)
  1774.     {
  1775.         got_int = FALSE;
  1776.         break;
  1777.     }
  1778.     }
  1779.     vim_free(file_str);
  1780.     FreeWild(num_files, files_found);
  1781.  
  1782. /*
  1783.  * we redraw the command below the lines that we have just listed
  1784.  * This is a bit tricky, but it saves a lot of screen updating.
  1785.  */
  1786.     cmdline_row = msg_row;    /* will put it back later */
  1787.  
  1788.     expand_interactively = FALSE;
  1789.     return OK;
  1790. }
  1791.  
  1792. /*
  1793.  * Prepare a string for expansion.
  1794.  * When expanding file names:  The string will be used with expand_wildcards().
  1795.  * Copy the file name into allocated memory and add a '*' at the end.
  1796.  * When expanding other names:    The string will be used with regcomp().  Copy
  1797.  * the name into allocated memory and add ".*" at the end.
  1798.  */
  1799.     char_u *
  1800. addstar(fname, len)
  1801.     char_u  *fname;
  1802.     int        len;
  1803. {
  1804.     char_u  *retval;
  1805.     int        i, j;
  1806.     int        new_len;
  1807.     char_u  *tail;
  1808.  
  1809.     if (expand_interactively && expand_context != EXPAND_FILES &&
  1810.                      expand_context != EXPAND_DIRECTORIES)
  1811.     {
  1812.     /*
  1813.      * Matching will be done internally (on something other than files).
  1814.      * So we convert the file-matching-type wildcards into our kind for
  1815.      * use with vim_regcomp().  First work out how long it will be:
  1816.      */
  1817.  
  1818.     /* for help tags the translation is done in find_help_tags() */
  1819.     if (expand_context == EXPAND_HELP)
  1820.         retval = vim_strnsave(fname, len);
  1821.     else
  1822.     {
  1823.         new_len = len + 2;        /* +2 for '^' at start, NUL at end */
  1824.         for (i = 0; i < len; i++)
  1825.         {
  1826.         if (fname[i] == '*' || fname[i] == '~')
  1827.             new_len++;        /* '*' needs to be replaced by ".*"
  1828.                        '~' needs to be replaced by "\~" */
  1829.  
  1830.         /* Buffer names are like file names.  "." should be literal */
  1831.         if (expand_context == EXPAND_BUFFERS && fname[i] == '.')
  1832.             new_len++;        /* "." becomes "\." */
  1833.         }
  1834.         retval = alloc(new_len);
  1835.         if (retval != NULL)
  1836.         {
  1837.         retval[0] = '^';
  1838.         j = 1;
  1839.         for (i = 0; i < len; i++, j++)
  1840.         {
  1841.             if (fname[i] == '\\' && ++i == len)    /* skip backslash */
  1842.             break;
  1843.  
  1844.             switch (fname[i])
  1845.             {
  1846.             case '*':   retval[j++] = '.';
  1847.                     break;
  1848.             case '~':   retval[j++] = '\\';
  1849.                     break;
  1850.             case '?':   retval[j] = '.';
  1851.                     continue;
  1852.             case '.':   if (expand_context == EXPAND_BUFFERS)
  1853.                     retval[j++] = '\\';
  1854.                     break;
  1855.             }
  1856.             retval[j] = fname[i];
  1857.         }
  1858.         retval[j] = NUL;
  1859.         }
  1860.     }
  1861.     }
  1862.     else
  1863.     {
  1864.     retval = alloc(len + 4);
  1865.     if (retval != NULL)
  1866.     {
  1867.         STRNCPY(retval, fname, len);
  1868.         retval[len] = NUL;
  1869. #ifndef macintosh
  1870.         if (!expand_set_path)
  1871.         backslash_halve(retval, TRUE);    /* remove some backslashes */
  1872. #endif
  1873.         len = STRLEN(retval);
  1874.  
  1875.         /*
  1876.          * Don't add a star to ~, ~user, $var or `cmd`.
  1877.          * ~ would be at the start of the tail.
  1878.          * $ could be anywhere in the tail.
  1879.          * ` could be anywhere in the file name.
  1880.          */
  1881.         tail = gettail(retval);
  1882.         if (*tail != '~' && vim_strchr(tail, '$') == NULL
  1883.                        && vim_strchr(retval, '`') == NULL)
  1884.         {
  1885. #ifdef MSDOS
  1886.         /*
  1887.          * if there is no dot in the file name, add "*.*" instead of
  1888.          * "*".
  1889.          */
  1890.         for (i = len - 1; i >= 0; --i)
  1891.             if (vim_strchr((char_u *)".\\/:", retval[i]) != NULL)
  1892.             break;
  1893.         if (i < 0 || retval[i] != '.')
  1894.         {
  1895.             retval[len++] = '*';
  1896.             retval[len++] = '.';
  1897.         }
  1898. #endif
  1899.         retval[len++] = '*';
  1900.         }
  1901.         retval[len] = NUL;
  1902.     }
  1903.     }
  1904.     return retval;
  1905. }
  1906.  
  1907. /*
  1908.  * Must parse the command line so far to work out what context we are in.
  1909.  * Completion can then be done based on that context.
  1910.  * This routine sets two global variables:
  1911.  *  char_u *expand_pattern  The start of the pattern to be expanded within
  1912.  *                the command line (ends at the cursor).
  1913.  *  int expand_context        The type of thing to expand.  Will be one of:
  1914.  *
  1915.  *  EXPAND_UNSUCCESSFUL        Used sometimes when there is something illegal on
  1916.  *                the command line, like an unknown command.    Caller
  1917.  *                should beep.
  1918.  *  EXPAND_NOTHING        Unrecognised context for completion, use char like
  1919.  *                a normal char, rather than for completion.    eg
  1920.  *                :s/^I/
  1921.  *  EXPAND_COMMANDS        Cursor is still touching the command, so complete
  1922.  *                it.
  1923.  *  EXPAND_BUFFERS        Complete file names for :buf and :sbuf commands.
  1924.  *  EXPAND_FILES        After command with XFILE set, or after setting
  1925.  *                with P_EXPAND set.    eg :e ^I, :w>>^I
  1926.  *  EXPAND_DIRECTORIES        In some cases this is used instead of the latter
  1927.  *                when we know only directories are of interest.  eg
  1928.  *                :set dir=^I
  1929.  *  EXPAND_SETTINGS        Complete variable names.  eg :set d^I
  1930.  *  EXPAND_BOOL_SETTINGS    Complete boolean variables only,  eg :set no^I
  1931.  *  EXPAND_TAGS            Complete tags from the files in p_tags.  eg :ta a^I
  1932.  *  EXPAND_HELP            Complete tags from the file 'helpfile'/tags
  1933.  *  EXPAND_EVENTS        Complete event names
  1934.  *  EXPAND_SYNTAX        Complete :syntax command arguments
  1935.  *  EXPAND_HIGHLIGHT        Complete highlight (syntax) group names
  1936.  *  EXPAND_AUGROUP        Complete autocommand group names
  1937.  *
  1938.  * -- webb.
  1939.  */
  1940.     static void
  1941. set_expand_context()
  1942. {
  1943.     char_u    *nextcomm;
  1944.     int        old_char = NUL;
  1945.  
  1946.     if (ccline.cmdfirstc != ':')    /* only expansion for ':' commands */
  1947.     {
  1948.     expand_context = EXPAND_NOTHING;
  1949.     return;
  1950.     }
  1951.  
  1952.     /*
  1953.      * Avoid a UMR warning from Purify, only save the character if it has been
  1954.      * written before.
  1955.      */
  1956.     if (ccline.cmdpos < ccline.cmdlen)
  1957.     old_char = ccline.cmdbuff[ccline.cmdpos];
  1958.     ccline.cmdbuff[ccline.cmdpos] = NUL;
  1959.     nextcomm = ccline.cmdbuff;
  1960.     while (nextcomm != NULL)
  1961.     nextcomm = set_one_cmd_context(nextcomm);
  1962.     ccline.cmdbuff[ccline.cmdpos] = old_char;
  1963. }
  1964.  
  1965. /*
  1966.  * Do the expansion based on the global variables expand_context and
  1967.  * expand_pattern -- webb.
  1968.  */
  1969.     static int
  1970. ExpandFromContext(pat, num_file, file, files_only, options)
  1971.     char_u  *pat;
  1972.     int        *num_file;
  1973.     char_u  ***file;
  1974.     int        files_only;
  1975.     int        options;
  1976. {
  1977.     vim_regexp    *prog;
  1978.     int        ret;
  1979.     int        flags;
  1980.     flags = 0;
  1981.     if (!files_only)
  1982.     flags |= EW_DIR;
  1983.     if (options & WILD_LIST_NOTFOUND)
  1984.     flags |= EW_NOTFOUND;
  1985.  
  1986.     if (!expand_interactively || expand_context == EXPAND_FILES)
  1987.     return expand_wildcards(1, &pat, num_file, file, flags|EW_FILE);
  1988.     else if (expand_context == EXPAND_DIRECTORIES)
  1989.     {
  1990.     int    free_pat = FALSE;
  1991.     int    i;
  1992.  
  1993.     /* for ":set path=" we need to remove backslashes for escaped space */
  1994.     if (expand_set_path)
  1995.     {
  1996.         free_pat = TRUE;
  1997.         pat = vim_strsave(pat);
  1998.         for (i = 0; pat[i]; ++i)
  1999.         if (pat[i] == '\\' && pat[i + 1] == '\\' &&
  2000.                       pat[i + 2] == '\\' && pat[i + 3] == ' ')
  2001.             STRCPY(pat + i, pat + i + 3);
  2002.     }
  2003.  
  2004.     ret = expand_wildcards(1, &pat, num_file, file,
  2005.                          (flags | EW_DIR) & ~EW_FILE);
  2006.     if (free_pat)
  2007.         vim_free(pat);
  2008.     return ret;
  2009.     }
  2010.  
  2011.     *file = (char_u **)"";
  2012.     *num_file = 0;
  2013.     if (expand_context == EXPAND_OLD_SETTING)
  2014.     return ExpandOldSetting(num_file, file);
  2015.  
  2016.     if (expand_context == EXPAND_HELP)
  2017.     return find_help_tags(pat, num_file, file);
  2018.  
  2019.     set_reg_ic(pat);        /* set reg_ic according to p_ic, p_scs and pat */
  2020.  
  2021.     if (expand_context == EXPAND_BUFFERS)
  2022.     return ExpandBufnames(pat, num_file, file, options);
  2023.     else if (expand_context == EXPAND_TAGS)
  2024.     return find_tags(pat, num_file, file, TAG_REGEXP | TAG_NAMES, MAXCOL);
  2025.  
  2026.     prog = vim_regcomp(pat, (int)p_magic);
  2027.     if (prog == NULL)
  2028.     return FAIL;
  2029.  
  2030.     if (expand_context == EXPAND_COMMANDS)
  2031.     ret = ExpandGeneric(prog, num_file, file, get_command_name);
  2032.     else if (expand_context == EXPAND_SETTINGS ||
  2033.                        expand_context == EXPAND_BOOL_SETTINGS)
  2034.     ret = ExpandSettings(prog, num_file, file);
  2035. #ifdef USE_GUI
  2036.     else if (expand_context == EXPAND_MENUS)
  2037.     ret = ExpandGeneric(prog, num_file, file, get_menu_name);
  2038. #endif
  2039. #ifdef SYNTAX_HL
  2040.     else if (expand_context == EXPAND_SYNTAX)
  2041.     {
  2042.     reg_ic = TRUE;
  2043.     ret = ExpandGeneric(prog, num_file, file, get_syntax_name);
  2044.     }
  2045. #endif
  2046.     else if (expand_context == EXPAND_HIGHLIGHT)
  2047.     {
  2048.     reg_ic = TRUE;
  2049.     ret = ExpandGeneric(prog, num_file, file, get_highlight_name);
  2050.     }
  2051. #ifdef AUTOCMD
  2052.     else if (expand_context == EXPAND_EVENTS)
  2053.     {
  2054.     reg_ic = TRUE;
  2055.     ret = ExpandGeneric(prog, num_file, file, get_event_name);
  2056.     }
  2057.     else if (expand_context == EXPAND_AUGROUP)
  2058.     {
  2059.     reg_ic = TRUE;
  2060.     ret = ExpandGeneric(prog, num_file, file, get_augroup_name);
  2061.     }
  2062. #endif
  2063.     else
  2064.     ret = FAIL;
  2065.  
  2066.     vim_free(prog);
  2067.     return ret;
  2068. }
  2069.  
  2070. /*
  2071.  * Expand a list of names.
  2072.  *
  2073.  * Generic function for command line completion.  It calls a function to
  2074.  * obtain strings, one by one.    The strings are matched against a regexp
  2075.  * program.  Matching strings are copied into an array, which is returned.
  2076.  *
  2077.  * Returns OK when no problems encountered, FAIL for error (out of memory).
  2078.  */
  2079.     int
  2080. ExpandGeneric(prog, num_file, file, func)
  2081.     vim_regexp    *prog;
  2082.     int        *num_file;
  2083.     char_u    ***file;
  2084.     char_u    *((*func)__ARGS((int))); /* returns a string from the list */
  2085. {
  2086.     int i;
  2087.     int count = 0;
  2088.     int    loop;
  2089.     char_u  *str;
  2090.  
  2091.     /* do this loop twice:
  2092.      * loop == 0: count the number of matching names
  2093.      * loop == 1: copy the matching names into allocated memory
  2094.      */
  2095.     for (loop = 0; loop <= 1; ++loop)
  2096.     {
  2097.     for (i = 0; ; ++i)
  2098.     {
  2099.         str = (*func)(i);
  2100.         if (str == NULL)        /* end of list */
  2101.         break;
  2102.         if (*str == NUL)        /* skip empty strings */
  2103.         continue;
  2104.  
  2105.         if (vim_regexec(prog, str, TRUE))
  2106.         {
  2107.         if (loop)
  2108.             (*file)[count] = vim_strsave_escaped(str,
  2109.                               (char_u *)" \t\\.");
  2110.         ++count;
  2111.         }
  2112.     }
  2113.     if (loop == 0)
  2114.     {
  2115.         if (count == 0)
  2116.         return OK;
  2117.         *num_file = count;
  2118.         *file = (char_u **)alloc((unsigned)(count * sizeof(char_u *)));
  2119.         if (*file == NULL)
  2120.         {
  2121.         *file = (char_u **)"";
  2122.         return FAIL;
  2123.         }
  2124.         count = 0;
  2125.     }
  2126.     }
  2127.     return OK;
  2128. }
  2129.  
  2130. /*********************************
  2131.  *  Command line history stuff     *
  2132.  *********************************/
  2133.  
  2134. /*
  2135.  * Translate a history character to the associated type number.
  2136.  */
  2137.     static int
  2138. hist_char2type(c)
  2139.     int        c;
  2140. {
  2141.     if (c == ':')
  2142.     return HIST_CMD;
  2143.     if (c == '=')
  2144.     return HIST_EXPR;
  2145.     return HIST_SEARCH;        /* must be '?' or '/' */
  2146. }
  2147.  
  2148. /*
  2149.  * init_history() - Initialize the command line history.
  2150.  * Also used to re-allocate the history when the size changes.
  2151.  */
  2152.     static void
  2153. init_history()
  2154. {
  2155.     int        newlen;        /* new length of history table */
  2156.     char_u  **temp;
  2157.     int        i;
  2158.     int        j;
  2159.     int        type;
  2160.  
  2161.     /*
  2162.      * If size of history table changed, reallocate it
  2163.      */
  2164.     newlen = (int)p_hi;
  2165.     if (newlen != hislen)            /* history length changed */
  2166.     {
  2167.     for (type = 0; type < HIST_COUNT; ++type)   /* adjust three tables */
  2168.     {
  2169.         if (newlen)
  2170.         {
  2171.         temp = (char_u **)lalloc((long_u)(newlen * sizeof(char_u *)),
  2172.                                     TRUE);
  2173.         if (temp == NULL)   /* out of memory! */
  2174.         {
  2175.             if (type == 0)  /* first one: just keep the old length */
  2176.             {
  2177.             newlen = hislen;
  2178.             break;
  2179.             }
  2180.             /* Already changed one table, now we can only have zero
  2181.              * length for all tables. */
  2182.             newlen = 0;
  2183.             type = -1;
  2184.             continue;
  2185.         }
  2186.         }
  2187.         else
  2188.         temp = NULL;
  2189.         if (newlen == 0 || temp != NULL)
  2190.         {
  2191.         if (hisidx[type] < 0)        /* there are no entries yet */
  2192.         {
  2193.             for (i = 0; i < newlen; ++i)
  2194.             temp[i] = NULL;
  2195.         }
  2196.         else if (newlen > hislen)    /* array becomes bigger */
  2197.         {
  2198.             for (i = 0; i <= hisidx[type]; ++i)
  2199.             temp[i] = history[type][i];
  2200.             j = i;
  2201.             for ( ; i <= newlen - (hislen - hisidx[type]); ++i)
  2202.             temp[i] = NULL;
  2203.             for ( ; j < hislen; ++i, ++j)
  2204.             temp[i] = history[type][j];
  2205.         }
  2206.         else                /* array becomes smaller or 0 */
  2207.         {
  2208.             j = hisidx[type];
  2209.             for (i = newlen - 1; ; --i)
  2210.             {
  2211.             if (i >= 0)        /* copy newest entries */
  2212.                 temp[i] = history[type][j];
  2213.             else            /* remove older entries */
  2214.                 vim_free(history[type][j]);
  2215.             if (--j < 0)
  2216.                 j = hislen - 1;
  2217.             if (j == hisidx[type])
  2218.                 break;
  2219.             }
  2220.             hisidx[type] = newlen - 1;
  2221.         }
  2222.         vim_free(history[type]);
  2223.         history[type] = temp;
  2224.         }
  2225.     }
  2226.     hislen = newlen;
  2227.     }
  2228. }
  2229.  
  2230. /*
  2231.  * Check if command line 'str' is already in history.
  2232.  * If 'move_to_front' is TRUE, matching entry is moved to end of history.
  2233.  */
  2234.     static int
  2235. in_history(type, str, move_to_front)
  2236.     int        type;
  2237.     char_u  *str;
  2238.     int        move_to_front;    /* Move the entry to the front if it exists */
  2239. {
  2240.     int        i;
  2241.     int        last_i = -1;
  2242.  
  2243.     if (hisidx[type] < 0)
  2244.     return FALSE;
  2245.     i = hisidx[type];
  2246.     do
  2247.     {
  2248.     if (history[type][i] == NULL)
  2249.         return FALSE;
  2250.     if (STRCMP(str, history[type][i]) == 0)
  2251.     {
  2252.         if (!move_to_front)
  2253.         return TRUE;
  2254.         last_i = i;
  2255.         break;
  2256.     }
  2257.     if (--i < 0)
  2258.         i = hislen - 1;
  2259.     } while (i != hisidx[type]);
  2260.  
  2261.     if (last_i >= 0)
  2262.     {
  2263.     str = history[type][i];
  2264.     while (i != hisidx[type])
  2265.     {
  2266.         if (++i >= hislen)
  2267.         i = 0;
  2268.         history[type][last_i] = history[type][i];
  2269.         last_i = i;
  2270.     }
  2271.     history[type][i] = str;
  2272.     return TRUE;
  2273.     }
  2274.     return FALSE;
  2275. }
  2276.  
  2277. /*
  2278.  * Add the given string to the given history.  If the string is already in the
  2279.  * history then it is moved to the front.  "histype" may be HIST_CMD,
  2280.  * HIST_SEARCH or HIST_EXPR.
  2281.  */
  2282.     void
  2283. add_to_history(histype, new_entry)
  2284.     int        histype;
  2285.     char_u    *new_entry;
  2286. {
  2287.     static int    last_maptick = -1;    /* last seen maptick */
  2288.  
  2289.     if (hislen == 0)        /* no history */
  2290.     return;
  2291.  
  2292.     /*
  2293.      * Searches inside the same mapping overwrite each other, so that only
  2294.      * the last line is kept.  Be careful not to remove a line that was moved
  2295.      * down, only lines that were added.
  2296.      */
  2297.     if (histype == HIST_SEARCH)
  2298.     {
  2299.     if (maptick == last_maptick)
  2300.     {
  2301.         /* Current line is from the same mapping, remove it */
  2302.         vim_free(history[HIST_SEARCH][hisidx[HIST_SEARCH]]);
  2303.         history[HIST_SEARCH][hisidx[HIST_SEARCH]] = NULL;
  2304.         if (--hisidx[HIST_SEARCH] < 0)
  2305.         hisidx[HIST_SEARCH] = hislen - 1;
  2306.     }
  2307.     last_maptick = -1;
  2308.     }
  2309.     if (!in_history(histype, new_entry, TRUE))
  2310.     {
  2311.     if (++hisidx[histype] == hislen)
  2312.         hisidx[histype] = 0;
  2313.     vim_free(history[histype][hisidx[histype]]);
  2314.     history[histype][hisidx[histype]] = vim_strsave(new_entry);
  2315.     if (histype == HIST_SEARCH)
  2316.         last_maptick = maptick;
  2317.     }
  2318. }
  2319.  
  2320. #ifdef VIMINFO
  2321. static char_u **viminfo_history[HIST_COUNT] = {NULL, NULL, NULL};
  2322. static int    viminfo_hisidx[HIST_COUNT] = {0, 0, 0};
  2323. static int    viminfo_hislen[HIST_COUNT] = {0, 0, 0};
  2324. static int    viminfo_add_at_front = FALSE;
  2325.  
  2326. static int    hist_type2char __ARGS((int type, int use_question));
  2327.  
  2328. /*
  2329.  * Translate a history type number to the associated character.
  2330.  */
  2331.     static int
  2332. hist_type2char(type, use_question)
  2333.     int        type;
  2334.     int        use_question;        /* use '?' instead of '/' */
  2335. {
  2336.     if (type == HIST_CMD)
  2337.     return ':';
  2338.     if (type == HIST_SEARCH)
  2339.     {
  2340.     if (use_question)
  2341.         return '?';
  2342.     else
  2343.         return '/';
  2344.     }
  2345.     return '=';
  2346. }
  2347.  
  2348. /*
  2349.  * Prepare for reading the history from the viminfo file.
  2350.  * This allocates history arrays to store the read history lines.
  2351.  */
  2352.     void
  2353. prepare_viminfo_history(asklen)
  2354.     int        asklen;
  2355. {
  2356.     int        i;
  2357.     int        num;
  2358.     int        type;
  2359.     int        len;
  2360.  
  2361.     init_history();
  2362.     viminfo_add_at_front = (asklen != 0);
  2363.     if (asklen > hislen)
  2364.     asklen = hislen;
  2365.  
  2366.     for (type = 0; type < HIST_COUNT; ++type)
  2367.     {
  2368.     /*
  2369.      * Count the number of empty spaces in the history list.  If there are
  2370.      * more spaces available than we request, then fill them up.
  2371.      */
  2372.     for (i = 0, num = 0; i < hislen; i++)
  2373.         if (history[type][i] == NULL)
  2374.         num++;
  2375.     len = asklen;
  2376.     if (num > len)
  2377.         len = num;
  2378.     if (len <= 0)
  2379.         viminfo_history[type] = NULL;
  2380.     else
  2381.         viminfo_history[type] =
  2382.            (char_u **)lalloc((long_u)(len * sizeof(char_u *)), FALSE);
  2383.     if (viminfo_history[type] == NULL)
  2384.         len = 0;
  2385.     viminfo_hislen[type] = len;
  2386.     viminfo_hisidx[type] = 0;
  2387.     }
  2388. }
  2389.  
  2390. /*
  2391.  * Accept a line from the viminfo, store it in the history array when it's
  2392.  * new.
  2393.  */
  2394.     int
  2395. read_viminfo_history(line, fp)
  2396.     char_u  *line;
  2397.     FILE    *fp;
  2398. {
  2399.     int        type;
  2400.  
  2401.     type = hist_char2type(line[0]);
  2402.     if (viminfo_hisidx[type] < viminfo_hislen[type])
  2403.     {
  2404.     viminfo_readstring(line);
  2405.     if (!in_history(type, line + 1, viminfo_add_at_front))
  2406.         viminfo_history[type][viminfo_hisidx[type]++] =
  2407.                             vim_strsave(line + 1);
  2408.     }
  2409.     return vim_fgets(line, LSIZE, fp);
  2410. }
  2411.  
  2412.     void
  2413. finish_viminfo_history()
  2414. {
  2415.     int idx;
  2416.     int i;
  2417.     int    type;
  2418.  
  2419.     for (type = 0; type < HIST_COUNT; ++type)
  2420.     {
  2421.     if (history[type] == NULL)
  2422.         return;
  2423.     idx = hisidx[type] + viminfo_hisidx[type];
  2424.     if (idx >= hislen)
  2425.         idx -= hislen;
  2426.     else if (idx < 0)
  2427.         idx = hislen - 1;
  2428.     if (viminfo_add_at_front)
  2429.         hisidx[type] = idx;
  2430.     else
  2431.     {
  2432.         if (hisidx[type] == -1)
  2433.         hisidx[type] = hislen - 1;
  2434.         do
  2435.         {
  2436.         if (history[type][idx] != NULL)
  2437.             break;
  2438.         if (++idx == hislen)
  2439.             idx = 0;
  2440.         } while (idx != hisidx[type]);
  2441.         if (idx != hisidx[type] && --idx < 0)
  2442.         idx = hislen - 1;
  2443.     }
  2444.     for (i = 0; i < viminfo_hisidx[type]; i++)
  2445.     {
  2446.         vim_free(history[type][idx]);
  2447.         history[type][idx] = viminfo_history[type][i];
  2448.         if (--idx < 0)
  2449.         idx = hislen - 1;
  2450.     }
  2451.     vim_free(viminfo_history[type]);
  2452.     viminfo_history[type] = NULL;
  2453.     }
  2454. }
  2455.  
  2456.     void
  2457. write_viminfo_history(fp)
  2458.     FILE    *fp;
  2459. {
  2460.     int        i;
  2461.     int        type;
  2462.     int        num_saved;
  2463.  
  2464.     init_history();
  2465.     if (hislen == 0)
  2466.     return;
  2467.     for (type = 0; type < HIST_COUNT; ++type)
  2468.     {
  2469.     num_saved = get_viminfo_parameter(hist_type2char(type, FALSE));
  2470.     if (num_saved == 0)
  2471.         continue;
  2472.     if (num_saved < 0)  /* Use default */
  2473.         num_saved = hislen;
  2474.     fprintf(fp, "\n# %s History (newest to oldest):\n",
  2475.                 type == HIST_CMD ? "Command Line" :
  2476.                 type == HIST_SEARCH ? "Search String" :
  2477.                             "Expression");
  2478.     if (num_saved > hislen)
  2479.         num_saved = hislen;
  2480.     i = hisidx[type];
  2481.     if (i >= 0)
  2482.         while (num_saved--)
  2483.         {
  2484.         if (history[type][i] != NULL)
  2485.         {
  2486.             putc(hist_type2char(type, TRUE), fp);
  2487.             viminfo_writestring(fp, history[type][i]);
  2488.         }
  2489.         if (--i < 0)
  2490.             i = hislen - 1;
  2491.         }
  2492.     }
  2493. }
  2494. #endif /* VIMINFO */
  2495.  
  2496. #ifdef FKMAP
  2497. /*
  2498.  * Write a character at the current cursor+offset position.
  2499.  * It is directly written into the command buffer block.
  2500.  */
  2501.     void
  2502. cmd_pchar(c, offset)
  2503.     int        c, offset;
  2504. {
  2505.     if (ccline.cmdpos + offset >= ccline.cmdlen || ccline.cmdpos + offset < 0)
  2506.     {
  2507.     EMSG("cmd_pchar beyond the command length");
  2508.     return;
  2509.     }
  2510.     ccline.cmdbuff[ccline.cmdpos + offset] = (char_u)c;
  2511. }
  2512.  
  2513.     int
  2514. cmd_gchar(offset)
  2515.     int        offset;
  2516. {
  2517.     if (ccline.cmdpos + offset >= ccline.cmdlen || ccline.cmdpos + offset < 0)
  2518.     {
  2519.     /*  EMSG("cmd_gchar beyond the command length"); */
  2520.     return NUL;
  2521.     }
  2522.     return (int)ccline.cmdbuff[ccline.cmdpos + offset];
  2523. }
  2524. #endif
  2525.